package utils

import (
	"bytes"
	"fmt"
	"strings"
)

var (
	HEAD_SPLITER = []byte{0x0A, 0x0A}
)

type head_kv struct {
	k, v string
}

type DataPacakageDecode struct {
	decodestep         int8
	head               []head_kv
	head_bodyl         int
	body_l             int // 收到的body大小
	head_raw           BytesBuilder
	latest_cache       BytesBuilder
	body_raw           BytesBuilder
	LatestCacheMaxSize int
	OnPackFunc         func(sender *DataPacakageDecode)
}

func NewDataPacakageDecode() *DataPacakageDecode {
	rval := &DataPacakageDecode{}
	return rval
}

func NewDataPacakageDecodeFromBuf(buf []byte) *DataPacakageDecode {
	rval := &DataPacakageDecode{}
	rval.InputBuf(buf)
	return rval
}

func (this *DataPacakageDecode) Reset() {
	this.decodestep = -1
}

/*
*

	引用数据, 重新编码将会覆盖
*/
func (this *DataPacakageDecode) GetBodyBuf() []byte {
	return this.body_raw.Bytes()
}

func (this *DataPacakageDecode) GetBodyBufCopy() []byte {
	return this.body_raw.CloneBuf()
}

/*
*

	-1: 错误
	 1: 正确
*/
func (this *DataPacakageDecode) decodeHead() int {
	str := string(this.head_raw.Buff(0, this.head_raw.Len()-2))
	strs := strings.Split(str, "\n")
	this.head = make([]head_kv, 0, len(strs))
	for i := 0; i < len(strs); i++ {
		var kv head_kv
		kv.k, kv.v = Split2Str(strs[i], ":")
		kv.k = Trim(strings.ToLower(kv.k))
		if len(kv.k) > 0 {
			kv.v = Trim(kv.v)
			this.head = append(this.head, kv)
			if kv.k == "len" {
				this.head_bodyl = StrToIntDef(kv.v, 0)
			}
		}
	}
	return 1
}

func (this *DataPacakageDecode) Status() string {
	if this.decodestep == 1 {
		return fmt.Sprintf("head-cache:[%s]\n[%s]\n", this.head_raw.String(), this.latest_cache.String())
	}
	return fmt.Sprintf("step:%d, head-cache:%d, bodyl:%d/%d", this.decodestep, this.head_raw.Len(), this.body_raw.Len(), this.head_bodyl)
}

/*
	   -1: err
		0: need more
		1: head
		2: decode body
*/
func (this *DataPacakageDecode) InputByte(v byte) int {
	if this.LatestCacheMaxSize > 0 && this.latest_cache.Len() > this.LatestCacheMaxSize {
		this.latest_cache.Cleanup()
	}

	if this.LatestCacheMaxSize > 0 {
		this.latest_cache.WriteByte(v)
	}

	if this.decodestep <= 0 {
		this.decodestep = 1
		this.body_l = 0
		this.head_bodyl = 0
		this.head_raw.Cleanup()
		this.body_raw.Cleanup()
	}

	if this.decodestep == 1 {
		this.head_raw.WriteByte(v)
		l := this.head_raw.Len()
		if l >= 2 {
			if this.head_raw.Index(l-2, HEAD_SPLITER) >= 0 {
				r := this.decodeHead()
				if r == -1 {
					this.decodestep = -1
					return 0
				}
				if this.head_bodyl == 0 { // 没有body
					if this.OnPackFunc != nil {
						this.OnPackFunc(this)
					}
					this.decodestep = -1
					return 1
				}
				this.decodestep = 2
				return 1
			}
		}
		if l > 4096 {
			this.decodestep = -1
			return -1
		}
		return 0
	} else if this.decodestep == 2 {
		this.body_raw.WriteByte(v)
		this.body_l++
		if this.body_l >= this.head_bodyl {
			if this.OnPackFunc != nil {
				this.OnPackFunc(this)
			}
			this.decodestep = -1
			return 2
		}
		return 0
	}

	return 0
}

func (this *DataPacakageDecode) GetHead(k string, def string) string {
	for i := 0; i < len(this.head); i++ {
		if this.head[i].k == k {
			return this.head[i].v
		}
	}
	return def
}

func (this *DataPacakageDecode) BodyLength() int {
	return this.head_bodyl
}

func (this *DataPacakageDecode) InputBuf(buf []byte) {
	for i := 0; i < len(buf); i++ {
		this.InputByte(buf[i])
	}
}

func (this *DataPacakageDecode) ResetBuf() {
	this.head_raw.Reset()
	this.body_raw.Reset()
}

func (this *DataPacakageDecode) DecodeFromBuf(buf []byte) error {
	idx := bytes.Index(buf, HEAD_SPLITER)
	if idx == -1 {
		return fmt.Errorf("非法的数据包, 缺少头部分隔符")
	}
	this.head_raw.Write(buf[:idx+len(HEAD_SPLITER)])
	this.decodeHead()
	this.body_raw.Write(buf[idx+len(HEAD_SPLITER):])
	return nil
}
